package com.extsci.webmail.web.service;

import com.extsci.webmail.common.entity.http.*;
import com.extsci.webmail.common.entity.mail.Attachment;
import com.extsci.webmail.common.entity.mail.Mail;
import com.extsci.webmail.common.entity.mail.MailUser;
import com.extsci.webmail.common.type.FieldType;
import com.extsci.webmail.common.type.MailBoxType;
import com.extsci.webmail.common.type.MailProtocolType;
import com.extsci.webmail.common.type.SortType;
import com.extsci.webmail.common.util.MyFileUtils;
import com.extsci.webmail.common.util.PinYinUtil;
import com.extsci.webmail.common.util.TimeUtils;
import com.extsci.webmail.exception.AttachmentException;
import com.extsci.webmail.web.client.UserServiceClient;
import com.sun.mail.imap.AppendUID;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import com.yanchang.common.context.BaseContextHandler;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.search.*;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 邮件处理服务
 * @author ccoke
 */
@Service
@Log4j
public class MailService {
    private static final int DEFAULT_CURRENT_PAGE = 0;
    private static final int DEFAULT_PAGESIZE = 10;
    private final Session sendSession;
    private final Session receiveSession;
    private final MailHandleService mailHandleService;
    private final AttachmentHandleService attachmentHandleService;
    private final UserServiceClient userServiceClient;

    // 默认后缀
    @Value("${webmail.domain}")
    private String defaultDomain;

    @Autowired
    public MailService(Session sendSession, Session receiveSession, MailHandleService mailHandleService, AttachmentHandleService attachmentHandleService, UserServiceClient userServiceClient) {
        this.sendSession = sendSession;
        this.receiveSession = receiveSession;
        this.mailHandleService = mailHandleService;
        this.attachmentHandleService = attachmentHandleService;
        this.userServiceClient = userServiceClient;
    }

    /**
     * 发送邮件
     */
    public ObjectRestResponse send(Mail mail){
        // 初始化邮件
        MimeMessage mimeMessage = null;
        try {
            mimeMessage = init(mail);
        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof AttachmentException) {
                log.error("附件错误:" + e.getMessage());
                return new ObjectRestResponse<>(ResponseStatus.PARSE_ATTACHMENT_ERROR);
            }
            log.error("初始化邮件:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_CREATE_EMAIL);
        }
        // 根据session获取传输对象
        Transport transport = null;
        try {
            transport = sendSession.getTransport();
            transport.connect(mail.getSenderUser().getAddress(), BaseContextHandler.getPassword());
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
            // 保存到已发送文件夹
            save2MailBox(new Message[]{mimeMessage}, MailBoxType.SENT);
            // 删除已上传附件
            deleteUploadAttachment(mail.getAttachments());
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("发送邮件:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_SEND_EMAIL);
        } finally {
            try {
                if (transport != null){
                    transport.close();
                }
            } catch (MessagingException e) {
            }
        }
    }

    /**
     * 保存邮件到草稿箱
     */
    public ObjectRestResponse save(Mail mail) {
        // 初始化邮件
        MimeMessage mimeMessage = null;
        try {
            mimeMessage = init(mail);
        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof AttachmentException) {
                log.error("附件错误:" + e.getMessage());
                return new ObjectRestResponse<>(ResponseStatus.PARSE_ATTACHMENT_ERROR);
            }
            log.error("初始化邮件:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_CREATE_EMAIL);
        }
        // 保存到草稿文件夹
        try {
            AppendUID[] uids = save2MailBox(new Message[]{mimeMessage}, MailBoxType.DRAFT);
            // 删除已上传附件(防止自动保存邮件时删除附件，改成不删除附件)
//            deleteUploadAttachment(mail.getAttachments());
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, uids[0].uid);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("保存邮件：" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_SAVE_EMAIL);
        }

    }

    /**
     * 初始化邮件
     */
    private MimeMessage init(Mail mail) throws UnsupportedEncodingException, MessagingException, AttachmentException {
        // 发件时间(可定时发送)
        mail.setSendDate(Optional.ofNullable(mail.getSendTimeStamp()).map(timestamp -> {return TimeUtils.timestrampToDate(mail.getSendTimeStamp());}).orElse(new Date()));
        // 监测附件地址,存在则获取附件真实地址
        attachmentHandleService.parseMailAttachments(mail.getAttachments());
        mail.setSenderUser(new MailUser(getEmailAddress(), Optional.ofNullable(mail.getSenderUser()).map(u -> u.getNickName()).orElse(BaseContextHandler.getName())));
        //创建MimeMessage
        return mailHandleService.createMimeMessage(mail, sendSession);
    }

    /**
     * 删除邮件（移动到回收站或彻底删除）
     */
    public ObjectRestResponse<String> remove(MailBoxType mailBoxType, MailListRequest mailList) {
        // 获取Session
        Store store = null;
        IMAPFolder srcFolder = null;
        IMAPFolder targetFolder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());

            srcFolder = (IMAPFolder) store.getFolder(mailBoxType.type);
            srcFolder.open(Folder.READ_WRITE);
            // 通过uid获取Message[]
            Message[] messages = getMessagesByUids(srcFolder,mailList.getUids());
            if (messages == null) {
                return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
            }
            // 移动到回收站
            if (!Optional.ofNullable(mailList.getIsDelete()).orElse(false)) {
                targetFolder = (IMAPFolder) store.getFolder(MailBoxType.TRASH.type);
                targetFolder.open(Folder.READ_WRITE);
                // 复制邮件到回收站
                if (mailList.getIsDelete() == null || !mailList.getIsDelete()){
                    srcFolder.copyMessages(messages, targetFolder);
                }
            }
            // 删除原邮件
            deleteMessages(srcFolder, messages);
            // 删除邮件附件目录
            attachmentHandleService.deleteAttachmentFolder(mailBoxType.type, mailList.getUids(), emailAddress);
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e){
            e.printStackTrace();
            log.info("移动到回收站:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_MOVE_EMAIL);
        }finally {
            close(store, srcFolder, targetFolder);
        }
    }

    /**
     * 从邮箱获取指定id邮件信息
     */
    public ObjectRestResponse<Mail> getMailByUid(MailBoxType mailBoxType, long id) {
        // 获取Session
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());
            // 获得指定邮箱
            folder = (IMAPFolder) store.getFolder(mailBoxType.type);
            // 以读方式打开
            folder.open(Folder.READ_ONLY);
            Message message = folder.getMessageByUID(id);
            if (message == null){
                return new ObjectRestResponse<>(ResponseStatus.NOTFOUNT);
            }
            Mail mail = mailHandleService.parseMimeMessage((MimeMessage) message, emailAddress, mailBoxType.type, id,true);
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, mail);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("邮件解析:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_PARSE_EMAIL);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("附件保存到本地:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_PARSE_EMAIL);
        } finally {
            close(store, folder);
        }
    }


    private Message[] getMessagesByUids(IMAPFolder folder, List<Long> uidList) throws MessagingException {
        // List<Long> -> long[]
        long[] uids = uidList.stream().mapToLong(t -> t.longValue()).toArray();
        Message[] messages = folder.getMessagesByUID(uids);
        List<Message> messagesTemp = new ArrayList<>();
        for (int i = 0; i < messages.length; i++) {
            // 剔除不存在的message
            if (messages[i] != null) {
                messagesTemp.add(messages[i]);
            }
        }
        return messagesTemp.size() == 0 ? null : messagesTemp.toArray(new Message[1]);
    }

    private void deleteMessages(Folder folder,Message ... messages) throws MessagingException {
        if (messages == null || messages.length < 1){
            return;
        }
        for (int i = 0; i < messages.length; i++) {
            messages[i].setFlag(Flags.Flag.DELETED, true);
        }
        folder.expunge();
    }



    /**
     * 清空回收站
     */
    public ObjectRestResponse<String> makeTrashEmpty() {
        // 获取Session
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String mailAddress = getEmailAddress();
            store.connect(mailAddress, BaseContextHandler.getPassword());
            folder = (IMAPFolder) store.getFolder(MailBoxType.TRASH.type);
            folder.open(Folder.READ_WRITE);
            Message[] messages = folder.getMessages();
            // 删除邮件
            deleteMessages(folder, messages);
            // 删除回收站附件目录
            String relativePath = MyFileUtils.contactUri(
                    attachmentHandleService.filePath,
                    MyFileUtils.FILE_SEPARATOR,
                    MyFileUtils.RESOURCE,
                    MyFileUtils.FILE_SEPARATOR,
                    mailAddress,
                    MyFileUtils.FILE_SEPARATOR,
                    MailBoxType.TRASH.type
            );

            MyFileUtils.deleteDir(new File(relativePath));
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("删除邮件:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_REMOVE_EMAIL);
        } finally {
            close(store, folder);
        }
    }


    /**
     * 将邮件保存到指定邮箱
     */
    public AppendUID[] save2MailBox(Message[] messages, MailBoxType mailBoxType) throws MessagingException {
        // 获取Session
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            store.connect(getEmailAddress(), BaseContextHandler.getPassword());
            // 获得指定文件夹
            folder = (IMAPFolder)store.getFolder(mailBoxType.type);
            // 以读写方式打开
            folder.open(Folder.READ_WRITE);
            // 追加到指定文件夹中
            return folder.appendUIDMessages(messages);
        } catch (MessagingException e) {
            e.printStackTrace();
            throw e;
        }finally {
            close(store, folder);
        }
    }

    /**
     * 移动邮件到目标目录
     */
    public ObjectRestResponse<String> move(MailBoxType srcMailBoxType, MailBoxType targetMailBoxType, MailListRequest mailList) {
        // 获取Session
        Store store = null;
        IMAPFolder srcFolder = null;
        IMAPFolder targetFolder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());

            srcFolder = (IMAPFolder) store.getFolder(srcMailBoxType.type);
            srcFolder.open(Folder.READ_WRITE);

            targetFolder = (IMAPFolder) store.getFolder(targetMailBoxType.type);
            targetFolder.open(Folder.READ_WRITE);
            Message[] messages = getMessagesByUids(srcFolder, mailList.getUids());
            if (messages == null) {
                return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
            }
            // 复制邮件到目标目录
            srcFolder.copyMessages(messages, targetFolder);
            // 删除邮件
            deleteMessages(srcFolder, messages);
            // 删除邮件附件目录
            attachmentHandleService.deleteAttachmentFolder(srcMailBoxType.type, mailList.getUids(), emailAddress);
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("移动邮件:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_MOVE_EMAIL);
        } finally {
            close(store, srcFolder, targetFolder);
        }
    }

    /**
     * 设置指定邮箱中邮件是否已读
     */
    public ObjectRestResponse<String> setIsSeen(MailBoxType mailBoxType, MailListRequest mailList) {
        // 获取Session
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            store.connect(getEmailAddress(), BaseContextHandler.getPassword());
            // 获得指定邮箱
            folder = (IMAPFolder) store.getFolder(mailBoxType.type);
            // 以读写方式打开
            folder.open(Folder.READ_WRITE);
            Message[] messages = getMessagesByUids(folder, mailList.getUids());
            if (messages != null){
                folder.setFlags(messages,new Flags(Flags.Flag.SEEN),mailList.getIsSeen());
            }
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("设置邮件已读:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_SET_EMAIL_IS_SEEN);
        } finally {
            close(store, folder);
        }
    }

    /**
     * 标记指定邮箱所有邮件已读
     */
    public ObjectRestResponse<String> setAllIsSeen(MailBoxType mailBoxType) {
        // 获取Session
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            store.connect(getEmailAddress(), BaseContextHandler.getPassword());
            folder = (IMAPFolder) store.getFolder(mailBoxType.type);
            folder.open(Folder.READ_WRITE);
            Message[] messages = folder.getMessages();
            // 标记所有邮件已读
            folder.setFlags(messages, new Flags(Flags.Flag.SEEN),true);
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("设置邮件已读:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_SET_EMAIL_IS_SEEN);
        } finally {
            close(store, folder);
        }
    }


    /**
     * 删除已上传附件
     */
    private void deleteUploadAttachment(List<Attachment> attachments){
        if (attachments == null || attachments.size() == 0) {
            return;
        }
        attachments.stream().forEach(attachment -> {
            File file = new File(attachment.getUri());
            if (file.exists()){
                MyFileUtils.deleteDir(file.getParentFile());
            }
        });
    }

    /**
     * 获取邮箱配额
     */
    public ObjectRestResponse<MailBoxResponse> getMailBoxQuota() {
        // 获取Session
        Store store = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            store.connect( getEmailAddress(), BaseContextHandler.getPassword());
            IMAPStore imapStore = (IMAPStore) store;
            Quota[] quotas = imapStore.getQuota(MailBoxType.INBOX.type);
            MailBoxResponse mailBox = new MailBoxResponse();
            Quota.Resource resource = quotas[0].resources[0];
            mailBox.setTotalQuota(resource.limit * 1024);
            mailBox.setUsageQuota(resource.usage * 1024);
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, mailBox);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("获取配额:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_GET_EMAIL_QUOTA);
        } finally {
            close(store);
        }
    }

    /**
     * 获取指定邮箱邮件列表
     */
    public ObjectRestResponse<MailResponse> getMailBox(MailBoxType mailBoxType, int currentPage, int pageSize, String keyword, FieldType fieldType, SortType sortType) {
        // 指定信箱所有邮件概略信息
        List<Mail> mails = getAllFromMailBox(mailBoxType);
        if (mails.size() == 0) {
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, new MailResponse(0, 0, mailBoxType.type.toLowerCase(), mails));
        }
        if (pageSize < 1){
            pageSize = DEFAULT_PAGESIZE;
        }
        if (currentPage < 0){
            currentPage = DEFAULT_CURRENT_PAGE;
        }
        // 关键词过滤
        if (StringUtils.isNotBlank(keyword)) {
            mails = mails.stream().filter(mail -> mail.getSubject().contains(keyword) || mail.getSenderUser().getAddress().contains(keyword)).collect(Collectors.toList());
        }
        // 没有搜索到结果
        if (mails.size() == 0) {
            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, new MailResponse(0, 0, mailBoxType.type.toLowerCase(), mails));
        }
        int totalPage = (int) Math.ceil(1.0 * mails.size() / pageSize);
        // 越界返回最后一页
        if (currentPage >= totalPage) {
            currentPage = totalPage - 1;
        }
        // 排序，分页
        List<Mail> result = mails.stream().sorted(new MailComparator(fieldType, sortType)).skip(currentPage * pageSize).limit(pageSize).collect(Collectors.toList());
        return new ObjectRestResponse<>(ResponseStatus.SUCCESS, new MailResponse(totalPage, currentPage, mailBoxType.type.toLowerCase(), result));
    }

    /**
     * 根据发件人、主题、发件日期获取收件箱内邮件id
     */
    public ObjectRestResponse<String> getMailUidFromInbox(Mail mail) {
        if (mail.getSenderUser().getAddress() == null) {
            return new ObjectRestResponse<>(ResponseStatus.PARAM_ERROR);
        }
        long sentTime = TimeUtils.timestrampToDate(mail.getSendTimeStamp()).getTime();
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());
            // 获得指定邮箱
            folder = (IMAPFolder) store.getFolder(MailBoxType.INBOX.type);
            // 以读方式打开
            folder.open(Folder.READ_ONLY);
            SearchTerm contentTerm = new AndTerm(
                    new FromTerm(new InternetAddress(mail.getSenderUser().getAddress())),
                    new SubjectTerm(mail.getSubject()));
            Message[] messages = folder.search(contentTerm);
            if (messages == null || messages.length == 0) {
                return new ObjectRestResponse<>(ResponseStatus.NOTFOUNT);
            }
            for (int i = 0; i < messages.length; i++) {
                if (messages[i].getSentDate().getTime() == sentTime) {
                    return new ObjectRestResponse<>(ResponseStatus.SUCCESS, String.valueOf(folder.getUID(messages[i])));
                }
            }
            return new ObjectRestResponse<>(ResponseStatus.NOTFOUNT);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("根据发件人、主题、发件日期获取收件箱内邮件id：" + e.getMessage());
            e.printStackTrace();
            return new ObjectRestResponse<>(ResponseStatus.NOTFOUNT);
        } finally {
            close(store, folder);
        }
    }


    /**
     * 获取邮箱内邮件数量
     * 收件箱为未读邮件数量
     * 其他邮箱为所有邮件数量
     */
    public ObjectRestResponse<Map<String, Integer>> getCountInMailBox() {
        MailBoxType[] mailBoxTypes = MailBoxType.values();
        Map<String, Integer> mailBoxMap = new HashMap<>(mailBoxTypes.length);
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());
            for (int i = 0; i < mailBoxTypes.length; i++) {
                folder = (IMAPFolder) store.getFolder(mailBoxTypes[i].type);
                // 收件箱只获取未读邮件数量
                mailBoxMap.put(mailBoxTypes[i].type.toLowerCase(), mailBoxTypes[i].equals(MailBoxType.INBOX) ? folder.getUnreadMessageCount() : folder.getMessageCount());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取邮箱邮件数量：" + e.getMessage());
        } finally {
            close(store, folder);
        }
        return new ObjectRestResponse<>(ResponseStatus.SUCCESS, mailBoxMap);
    }

    /**
     * 邮件排序内部类
     * @author ccoke
     */
    class MailComparator implements Comparator<Mail>{
        private final FieldType fieldType;
        private final SortType sortType;

        public MailComparator(FieldType fieldType, SortType sortType) {
            this.fieldType = fieldType;
            this.sortType = sortType;
        }

        @Override
        public int compare(Mail o1, Mail o2) {
            String a1, a2;
            if (FieldType.SENDER.equals(fieldType)) {
                a1 = PinYinUtil.getPinYinIndexString(Optional.ofNullable(o1.getSenderUser().getNickName()).orElse(o1.getSenderUser().getAddress()), false).toLowerCase();
                a2 = PinYinUtil.getPinYinIndexString(Optional.ofNullable(o2.getSenderUser().getNickName()).orElse(o2.getSenderUser().getAddress()), false).toLowerCase();
                return SortType.DESC.equals(sortType) ?  a2.compareTo(a1) : a1.compareTo(a2);
            }
            if (FieldType.SUBJECT.equals(fieldType)) {
                a1 = PinYinUtil.getPinYinIndexString(o1.getSubject(), false).toLowerCase();
                a2 = PinYinUtil.getPinYinIndexString(o2.getSubject(), false).toLowerCase();
                return SortType.DESC.equals(sortType) ? a2.compareTo(a1) : a1.compareTo(a2);
            }
            return SortType.DESC.equals(sortType) ? Long.compare(o2.getReceiveTimeStamp(), o1.getReceiveTimeStamp()) : Long.compare(o1.getReceiveTimeStamp(), o2.getReceiveTimeStamp());
        }
    }

    /**
     * 从指定邮箱获取所有邮件基本信息
     */
    private List<Mail> getAllFromMailBox(MailBoxType mailBoxType) {
        List<Mail> mails = new ArrayList<>();
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            String emailAddress = getEmailAddress();
            store.connect(emailAddress, BaseContextHandler.getPassword());
            // 获得指定邮箱
            folder = (IMAPFolder) store.getFolder(mailBoxType.type);
            // 以读方式打开
            folder.open(Folder.READ_ONLY);
            Message[] msgs = folder.getMessages();
            for (int i = msgs.length -1 ; i >= 0; i--) {
                // 简单解析邮件
                Mail mail = mailHandleService.parseMimeMessage((MimeMessage) msgs[i], emailAddress, mailBoxType.type.toLowerCase(), folder.getUID(msgs[i]), false);
                if (mailBoxType.equals(MailBoxType.DRAFT)){
                    mail.setIsDraft(true);
                }
                mails.add(mail);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("从邮箱获取所有邮件：" + e.getMessage());
        } finally {
            close(store, folder);
            return mails;
        }
    }

    /**
     * 获取最近联系人列表
     * @param count 联系人数量
     * @return 最近联系人列表
     */
    public ObjectRestResponse<Set<String>> getRecentSenders(int count) {
        Set<String> senders = new LinkedHashSet<>();
        String emailAddress = getEmailAddress();
        Store store = null;
        IMAPFolder folder = null;
        try {
            store = receiveSession.getStore(MailProtocolType.IMAP.type);
            store.connect(emailAddress, BaseContextHandler.getPassword());
            folder = (IMAPFolder) store.getFolder(MailBoxType.SENT.type);
            folder.open(Folder.READ_ONLY);
            Message[] messages = folder.getMessages();
            // 按加入顺序倒序
            for (int i = messages.length -1 ; i >= 0; i--) {
                // 获取收件人
                parseMailUsers(senders, mailHandleService.getReceiveAddress((MimeMessage) messages[i], null), count);
            }

            return new ObjectRestResponse<>(ResponseStatus.SUCCESS, senders);
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("最近联系人列表:" + e.getMessage());
            return new ObjectRestResponse<>(ResponseStatus.CANNOT_GET_RECENT_SENDERS);
        } finally {
            close(store, folder);
        }
    }

    /**
     * 解析邮件用户
     */
    private void parseMailUsers(Set<String> senders, List<MailUser> users, int count) {
        if (count == senders.size()) {
            return;
        }
        for (int i = 0; i < users.size() && senders.size() < count; i++) {
            senders.add(users.get(i).getAddress());
        }
    }

    /**
     * 获取邮件地址
     */
    public String getEmailAddress(){
        String domain = Optional.ofNullable(BaseContextHandler.getCompany())
                .map(companyId -> "null".equals(companyId) ? null : Integer.valueOf(companyId) )
                .map(id -> userServiceClient.getCompanyById(id))
                .map(company -> company.getEmailDomain())
                .orElse(defaultDomain);
        StringBuilder sb = new StringBuilder();
        String address = sb.append(BaseContextHandler.getUsername()).append("@").append(domain).toString();
        return address;
    }


    /**
     * finish
     */
    private void close(Store store, Folder ... folders){
        try {
            if (store != null) {
                store.close();
            }
            if (folders == null || folders.length < 1) {
                return;
            }
            for (int i = 0; i < folders.length; i++) {
                if (folders[i] != null && folders[i].isOpen()){
                    folders[i].close();
                }
            }
        } catch(MessagingException e){
            // 捕获了啥都不做
        }
    }
}
